﻿using System;
using System.Collections.Generic;
using BlobNet.Base.DataProviders;
using BlobNet.Base.Enums;
using BlobNet.Base.Storage;
using BlobNet.TestsCommon.UnitTests.Dummy;
using BlobNet.TestsCommon.Utils;
using NUnit.Framework;
using Rhino.Mocks;
using Rhino.Mocks.Impl;

namespace BlobNet.Base.Tests.UnitTests.BlobPartObjectBaseTests
{
    //TODO:refactor tests
    [TestFixture]
    [Category("Unit Tests")]
    public class BlobDomainTests
    {
        [TestFixtureSetUp]
        public void StartFixture()
        {
            RhinoMocks.Logger = new TextWriterExpectationLogger(Console.Out);
        }

        [Test]
        [Ignore]
        public void Can_Access_To_BlobParts()
        {
            Assert.Inconclusive("Just like any other statusHolder");
        }
        
        [Test]
        [Ignore]
        public void Can_Access_To_SubBlobDomains()
        {
            Assert.Inconclusive("Just like any other statusHolder");
        }

        [Test]
        [Ignore]
        public void Can_AssignBlobDomain_To_Another_BlobDomain()
        {
            Assert.Inconclusive();
        }

        [Test]
        public void Can_CreateBlobDomain_MemoryDefault()
        {
            DataProviderFactory.Provider = TestsHelper.GetStubDataProvider();//TODO: REMOVE USE DI
            var target = new DummyBlobDomainHolder();

            Assert.IsTrue(target.StatusStorage == StatusStorageType.Memory);
        }

        [Test]
        public void Can_Remove_BlobDomainWhenDb()
        {
            //Arrange
            var stubDbHelper = MockRepository.GenerateMock<IDataProvider>();
            DataProviderFactory.Provider = stubDbHelper;
            Guid id = Guid.NewGuid();
            stubDbHelper.Stub(x => x.CreateSchema(Arg<Guid>.Is.Equal(id)));
            stubDbHelper.Stub(x => x.RemoveSchema(Arg<Guid>.Is.Equal(id)));

            IStorageManager memPersistor, dbPersistor;
            IStorageManagerFactory factory = TestsHelper.GetStubFactory(out memPersistor, out dbPersistor);

            memPersistor.Stub(x => x.CanDettach()).Return(true);

            var target = new DummyBlobDomainHolder( id, factory);

            //Act
            target.ReleaseStatusResources();

            //Assert
            stubDbHelper.AssertWasCalled(x => x.RemoveSchema(id));
        }

        [Test]
        public void Can_Remove_BlobDomainWhenMemory()
        {
            //Arrange
            var stubDbHelper = MockRepository.GenerateStub<IDataProvider>();
            Guid id = Guid.NewGuid();
            stubDbHelper.Stub(x => x.RemoveSchema(Arg<Guid>.Is.Equal(id)));
            DataProviderFactory.Provider = stubDbHelper;//TODO: REMOVE USE DI
            var target = new DummyBlobDomainHolder();

            //act
            target.ReleaseStatusResources();

            //assert
            stubDbHelper.AssertWasNotCalled(x => x.RemoveSchema(id));
        }

        [Test]
        public void Can_BlobDomainKeepStatusInDataProvider()
        {
            //Arrange
            IDataProvider stubDbHelper = TestsHelper.GetStubDataProvider();
            DataProviderFactory.Provider = stubDbHelper;//TODO: REMOVE USE DI
            //Act
            var target = new DummyBlobDomainHolder();
            stubDbHelper.AssertWasCalled(x => x.CreateSchema(target.EntityId));

            //Assert
            Assert.IsTrue(target.StatusStorage == StatusStorageType.Memory);
        }

        [Test]
        [Ignore]
        public void Cant_AssignBlobDomain_To_Non_BlobDomain()
        {
            Assert.Inconclusive();
        }

        [Test]
        public void Cant_CreateBlobDomainHolder_With_Invalid_EntityId()
        {
            //Arrange
            var stubDbHelper = MockRepository.GenerateStub<IDataProvider>();
            stubDbHelper.Stub(x => x.CreateSchema(Arg<Guid>.Is.Anything));
            DataProviderFactory.Provider = stubDbHelper;//TODO: REMOVE USE DI

            //Assert
            Assert.Throws(typeof (ArgumentException), () => new DummyBlobDomainHolder(Guid.Empty));
        }

        [Test]
        [Ignore]
        public void Cant_RemoveBlobDomain_When_It_Has_SubblobDomainsAttached()
        {
            Assert.Inconclusive();
        }

        [Test]
        public void Can_Add_Object()
        {
            //store..
            throw new NotImplementedException("Just add object to domain");
        }

        [Test]
        public void Can_Update_Object()
        {
            //store..
            throw new NotImplementedException("Just add object to domain");
        }

        [Test]
        public void Can_Remove_Object()
        {
            throw new NotImplementedException("Just Remove object from domain");
        }

        [Test]
        public void Can_GetItems_By_Type()
        {
            throw new NotImplementedException("Method already implemented just test");
        }

        [Test]
        public void Can_Start_Transaction()
        {
            throw new NotImplementedException();
        }

        [Test]
        public void Can_Commit_Transaction()
        {
            throw new NotImplementedException();
        }

        [Test]
        public void Can_Rollback_Transaction()
        {
            throw new NotImplementedException();
        }
    }
}